package com.i2863.shiroDemo.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.i2863.shiroDemo.annotation.SysLog;
import com.i2863.shiroDemo.config.ShiroRealm;
import com.i2863.shiroDemo.dto.ResultInfo;
import com.i2863.shiroDemo.entity.Role;
import com.i2863.shiroDemo.entity.User;
import com.i2863.shiroDemo.service.IRoleService;
import com.i2863.shiroDemo.service.IUserService;
import com.i2863.shiroDemo.util.Pinyin;
import com.i2863.shiroDemo.util.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@Controller
@RequestMapping("role")
public class RoleController extends BaseController {

    @Resource
    private IRoleService roleService;
    @Resource
    private IUserService userService;

    @RequestMapping("list")
    public String list(Model model) {
        List<Role> list = roleService.list();
        list.remove(this.getSuperRole());
        model.addAttribute("roleList", list);
        model.addAttribute("size", list.size());
        model.addAttribute("roleId", list.size() > 0 ? list.get(0).getId() : 0);
        return "role/role_list";
    }

    @ResponseBody
    @RequestMapping("selectListData")
    public ResultInfo<List<Role>> selectListData() {
        List<Role> list = roleService.list();
        list.remove(this.getSuperRole());
        return new ResultInfo<>(list);
    }

    @GetMapping("add")
    @RequiresPermissions("role:add")
    public String toAdd() {
        return "role/role_add";
    }

    @GetMapping("edit/{roleId}")
    @RequiresPermissions("role:edit")
    public String toEdit(@PathVariable("roleId") Integer roleId, Model model) {
        Role role = roleService.getById(roleId);
        model.addAttribute("roleId", roleId);
        model.addAttribute("roleName", role.getRoleName());
        model.addAttribute("available", role.getAvailable());
        return "role/role_edit";
    }

    @ResponseBody
    @SysLog("添加角色")
    @RequestMapping("base/save")
    @RequiresPermissions(value = {"role:add", "role:edit"}, logical = Logical.OR)
    public ResultInfo<Boolean> baseSave(String roleName, int available) {
        Role role = new Role();
        if (checkName(roleName, available, role)) {
            return new ResultInfo<>(500, "角色名称不能重复！");
        }
/*        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        ShiroRealm realm = (ShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAuth();*/
        boolean b = roleService.saveRole(role);
        return new ResultInfo<>(b);
    }

    @ResponseBody
    @SysLog("编辑角色")
    @RequestMapping("base/edit")
    @RequiresPermissions(value = {"role:add", "role:edit"}, logical = Logical.OR)
    public ResultInfo<Boolean> baseEdit(Integer roleId, String roleName, int available) {
        Role role = roleService.getById(roleId);
        if (checkName(roleName, available, role)) {
            return new ResultInfo<>(500, "角色名称不能重复！");
        }
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        ShiroRealm realm = (ShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAuth();
        return new ResultInfo<>(roleService.updateById(role));
    }

    @ResponseBody
    @SysLog("编辑角色")
    @PostMapping("edit")
    @RequiresPermissions("role:edit")
    public ResultInfo<Boolean> save(Integer id, String roleName, Integer available) {
        Role role = roleService.getById(id);
        role.setAvailable(available);
        role.setRoleName(roleName);
        roleService.updateById(role);
        return new ResultInfo<>(roleService.saveRole(role));
    }

    @ResponseBody
    @SysLog("删除角色操作")
    @PostMapping("del/{roleId}")
    @RequiresPermissions("role:del")
    public ResultInfo<Boolean> delBatch(@PathVariable Integer roleId) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.in("role_id", roleId);
        List<User> userList = userService.list(wrapper);
        if (userList != null && userList.size() > 0) {
            return new ResultInfo<>("该角色存在用户，不能删除！");
        }
        return new ResultInfo<>(roleService.removeById(roleId));
    }

    @ResponseBody
    @SysLog("角色菜单权限变更")
    @RequestMapping("menuPer/save")
    @RequiresPermissions("role:edit")
    public ResultInfo<Object> save(int roleId, String permissionIds) {
        Role role = roleService.getById(roleId);
        if (role == null) {
            return new ResultInfo<>(500, "用户角色不存在");
        }

        role.setPermissionIds(StringUtils.isBlank(permissionIds) ? "" : "," + permissionIds);
        roleService.updateById(role);
        return new ResultInfo<>(200, "权限修改成功");
    }

    private boolean checkName(String roleName, int available, Role role) {
        role.setRoleName(roleName);
        role.setAvailable(available);
        role.setRoleCode(Pinyin.getPinYinHeadChar(role.getRoleName()));
        List<Role> roleList = roleService.list(new QueryWrapper<Role>().lambda().eq(Role::getRoleName, roleName));
        return roleList.size() > 0 && role.getId() == null;
    }
}